﻿using System;
using System.Net;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;

namespace ImageGrabberAPI
{
    public class ImageGrabber
    {
        public static Image ImageToFind { get; set; }
        private static string imgPath;

        public static List<Image> GetImage(string url, string format, short width = 500, short height = 500, bool takeOnlyFirst = false)
        {
            List<Image> imageToFindList = null;
            try
            {
                using (WebClient web = new WebClient())
                {
                    ImageToFind = null;
                    imgPath = string.Empty;
                    web.Headers.Add("user-agent", "Only a test!");
                    web.Proxy = WebRequest.DefaultWebProxy;
                    string page = web.DownloadString(url);
                    var pageParts = page.Split(new string[] { "src=" }, StringSplitOptions.None);
                    foreach (string item in pageParts)
                    {
                        if (item.ToLower().Contains(String.Format(".{0}", format)))
                        {
                            imgPath = item.Substring(item.IndexOf("http://"), (item.IndexOf(String.Format(".{0}", format)) - item.IndexOf("http://") + 4));
                            ImageToFind = DownloadImage(imgPath);
                            if (ImageToFind.Size.Width > width && ImageToFind.Height > height)
                            {
                                ImageToFind.Tag = GetTag(format);
                                imageToFindList.Add(ImageToFind);
                                if (takeOnlyFirst)
                                    break;
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }

            return imageToFindList;

        }


        public static Image GetFirstImage(string url, string format, short width = 500, short height = 500)
        {
            ImageToFind = GetImage(url, format, width, height, true).FirstOrDefault();
            if (ImageToFind == null)
                return null;
            return ImageToFind;
        }

        public static Image GetImageByMark(string url, string mark, string format = "jpg")
        {
            try
            {
                using (WebClient web = new WebClient())
                {
                    ImageToFind = null;
                    imgPath = string.Empty;

                    string page = web.DownloadString(url);
                    int markIndex = page.IndexOf(mark);

                    int startIndex = page.IndexOf("src=", markIndex);
                    int endIndex = page.IndexOf("." + format, markIndex);

                    imgPath = page.Substring(startIndex + 5, endIndex + format.Length - (startIndex - 5)); // 5 here is 'src="'
                    ImageToFind = DownloadImage(imgPath);
                    ImageToFind.Tag = GetTag(format);
                }
            }
            catch (Exception)
            {
                throw;
            }
            return ImageToFind;
        }

        public static Image GetImageByMarkDeep(string url, string mark = "", string format = "jpg", int deepLevel = 0, int currentLevel = 0)
        {
            if (string.IsNullOrWhiteSpace(url))
                throw new ArgumentNullException("url cannot be null or empty");
            if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
                throw new UriFormatException(string.Format("{0} this url format is invalid!", url));
            ImageToFind = null;
            using (WebClient web = new WebClient())
            {
                string page = web.DownloadString(url);

                List<Uri> pageParts = LinkFinder.FindUrisByMark(page, "href", mark);// LinkFinder.FindUris(); //page.Split(new string[] { "src=", "href=" }, StringSplitOptions.RemoveEmptyEntries);

                for (int i = 1; i < pageParts.Count; i++) // From 1, because we can just skip first block
                {
                    var uri = pageParts[i].ToString();
                    if (!uri.Contains("http://"))
                        uri = uri.Insert(0, "http://");
                    if (!string.IsNullOrWhiteSpace(mark) && !uri.Contains(mark))
                        continue;

                    if (ImageToFind != null)
                        break;
                    try
                    {
                        if (uri.ToLower().Contains(String.Format(".{0}", format)))
                        {
                            imgPath = uri.Substring(uri.IndexOf("http://"), (uri.IndexOf(String.Format(".{0}", format)) - uri.IndexOf("http://") + 4));
                            ImageToFind = DownloadImage(imgPath);
                            if (ImageToFind != null && ImageToFind.Size.Width > 900 && ImageToFind.Height > 900) // search only for "wallpapers"
                            {
                                ImageToFind.Tag = GetTag(format);
                                break;
                            }
                            else
                            {
                                ImageToFind = null;
                                continue;
                            }

                        }

                        if (deepLevel >= currentLevel)
                        {
                            string urlPath = uri;
                            ImageToFind = GetImageByMarkDeep(urlPath, mark, format, deepLevel - 1, currentLevel + 1);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw;
                    }
                }
            }
            return ImageToFind;
        }

        private static string GetTag(string format)
        {
            return imgPath.Substring(imgPath.LastIndexOf("/") + 1, (imgPath.IndexOf("." + format) + format.Length - imgPath.LastIndexOf("/")));
        }

        public static Image DownloadImage(string _URL)
        {
            try
            {
                WebRequest requestPic = WebRequest.Create(_URL);
                WebResponse responsePic = requestPic.GetResponse();
                return Image.FromStream(responsePic.GetResponseStream());
            }
            catch
            {
                throw;
            }
        }
    }
}
